
"""network compatibility module, for easy stubbing (see tests)"""

from google.appengine.api import urlfetch
import xmlrpclib
import logging
from cStringIO import StringIO

log = logging.getLogger()

class FetchHTTP(object):
    """transport with interface as much like httplib.HTTP as possible"""
    method_map = {
        ## enterprise!
        'GET': urlfetch.GET,
        'POST': urlfetch.POST,
        'HEAD': urlfetch.HEAD,
        'PUT': urlfetch.PUT,
        'DELETE': urlfetch.DELETE
    }
    def __init__(self, host, protocol='http'):
        self.protocol = protocol
        self.host = host
        self.method = None
        self.url = None
        self.headers = {}
        self.response = None
        
    def endheaders(self):
        """Indicate that the last header line has been sent to the server."""

    def getfile(self):
        "Provide a getfile, since the superclass' does not use this concept."
        return StringIO(self.response.content)
        
    def getreply(self):
        """Compat definition since superclass does not define it.

        Returns a tuple consisting of:
        - server status code (e.g. '200' if all goes well)
        - server "reason" corresponding to status code
        - any RFC822 headers in the response from the server
        """
        return (self.response.status_code, self.response.content, self.response.headers)

    def putheader(self, header, value):
        """Send a request header line to the server.

        For example: h.putheader('Accept', 'text/html')
        """
        self.headers[header] = value
    
    def putrequest(self, method, url, skip_host=0, skip_accept_encoding=0):
        """Send a request to the server.

        `method' specifies an HTTP request method, e.g. 'GET'.
        `url' specifies the object being requested, e.g. '/index.html'.
        `skip_host' if True does not add automatically a 'Host:' header
        `skip_accept_encoding' if True does not add automatically an
           'Accept-Encoding:' header
        """
        # log.info(url)
        self.method = self.method_map[method]
        self.url = url

    def send(self, req_body):
        """Send req_body to the server."""
        url = self.protocol + '://' + self.host + self.url
        log.info("sending request to %s", url)
        self.response = urlfetch.fetch(url, 
                            payload=req_body, method=self.method, headers=self.headers)

class FetchTransport(xmlrpclib.Transport):
    """a urlfetch.fetch based transport compatible with xmlrpclib.Transport"""
    ##
    # Connect to server.
    #
    # @param host Target host.
    # @return A connection handle.

    def make_connection(self, host):
        # create a HTTP connection object from a host descriptor
        host, extra_headers, x509 = self.get_host_info(host)
        return FetchHTTP(host)